From 8b744a05dda5268a8d8d241a054c5cadd3bcdf6e Mon Sep 17 00:00:00 2001 From: Karol Kuczmarski Date: Mon, 17 Apr 2017 19:48:56 +0100 Subject: [PATCH] Allow cargo:rustc-env in build scripts --- src/cargo/ops/cargo_compile.rs | 1 + src/cargo/ops/cargo_rustc/custom_build.rs | 17 +++++ src/cargo/ops/cargo_rustc/mod.rs | 23 +++++++ src/cargo/util/machine_message.rs | 1 + tests/build-script.rs | 80 ++++++++++++++++++++++- 5 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 1256787f4..ef5aa9274 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -670,6 +670,7 @@ fn scrape_target_config(config: &Config, triple: &str) library_paths: Vec::new(), library_links: Vec::new(), cfgs: Vec::new(), + env: Vec::new(), metadata: Vec::new(), rerun_if_changed: Vec::new(), warnings: Vec::new(), diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 4c1dca592..64f05f918 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -21,6 +21,8 @@ pub struct BuildOutput { pub library_links: Vec, /// Various `--cfg` flags to pass to the compiler pub cfgs: Vec, + /// Additional environment variables to run the compiler with. + pub env: Vec<(String, String)>, /// Metadata to pass to the immediate dependencies pub metadata: Vec<(String, String)>, /// Paths to trigger a rerun of this build script. @@ -255,6 +257,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) linked_libs: &parsed_output.library_links, linked_paths: &library_paths, cfgs: &parsed_output.cfgs, + env: &parsed_output.env, }); } @@ -321,6 +324,7 @@ impl BuildOutput { let mut library_paths = Vec::new(); let mut library_links = Vec::new(); let mut cfgs = Vec::new(); + let mut env = Vec::new(); let mut metadata = Vec::new(); let mut rerun_if_changed = Vec::new(); let mut warnings = Vec::new(); @@ -361,6 +365,7 @@ impl BuildOutput { "rustc-link-lib" => library_links.push(value.to_string()), "rustc-link-search" => library_paths.push(PathBuf::from(value)), "rustc-cfg" => cfgs.push(value.to_string()), + "rustc-env" => env.push(BuildOutput::parse_rustc_env(value, &whence)?), "warning" => warnings.push(value.to_string()), "rerun-if-changed" => rerun_if_changed.push(value.to_string()), _ => metadata.push((key.to_string(), value.to_string())), @@ -371,6 +376,7 @@ impl BuildOutput { library_paths: library_paths, library_links: library_links, cfgs: cfgs, + env: env, metadata: metadata, rerun_if_changed: rerun_if_changed, warnings: warnings, @@ -407,6 +413,17 @@ impl BuildOutput { } Ok((library_paths, library_links)) } + + pub fn parse_rustc_env(value: &str, whence: &str) + -> CargoResult<(String, String)> { + let mut iter = value.splitn(2, '='); + let name = iter.next(); + let val = iter.next(); + match (name, val) { + (Some(n), Some(v)) => Ok((n.to_owned(), v.to_owned())), + _ => bail!("Variable rustc-env has no value in {}: {}", whence, value), + } + } } /// Compute the `build_scripts` map in the `Context` which tracks what build diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 439046eb1..9d9c56d2c 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -305,12 +305,15 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc) -> CargoResult) -> CargoResult CargoResult<()> { + for key in build_scripts.to_link.iter() { + let output = build_state.get(key).chain_error(|| { + internal(format!("couldn't find build state for {}/{:?}", + key.0, key.1)) + })?; + if key.0 == *current_id { + for &(ref name, ref value) in output.env.iter() { + rustc.env(name, value); + } + } + } + Ok(()) + } } /// Link the compiled target (often of form foo-{metadata_hash}) to the diff --git a/src/cargo/util/machine_message.rs b/src/cargo/util/machine_message.rs index 1d4f33a86..5f917f85a 100644 --- a/src/cargo/util/machine_message.rs +++ b/src/cargo/util/machine_message.rs @@ -48,6 +48,7 @@ pub struct BuildScript<'a> { pub linked_libs: &'a [String], pub linked_paths: &'a [String], pub cfgs: &'a [String], + pub env: &'a [(String, String)], } impl<'a> Message for BuildScript<'a> { diff --git a/tests/build-script.rs b/tests/build-script.rs index 8d40474d2..e663f5abc 100644 --- a/tests/build-script.rs +++ b/tests/build-script.rs @@ -1575,6 +1575,82 @@ fn cfg_override_doc() { assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file()); } +#[test] +fn env_build() { + let build = project("builder") + .file("Cargo.toml", r#" + [package] + name = "builder" + version = "0.0.1" + authors = [] + build = "build.rs" + "#) + .file("src/main.rs", r#" + const FOO: &'static str = env!("FOO"); + fn main() {} + "#) + .file("build.rs", r#" + fn main() { + println!("cargo:rustc-env=FOO=foo"); + } + "#); + assert_that(build.cargo_process("build").arg("-v"), + execs().with_status(0)); +} + +#[test] +fn env_test() { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + build = "build.rs" + "#) + .file("build.rs", r#" + fn main() { + println!("cargo:rustc-env=FOO=foo"); + } + "#) + .file("src/lib.rs", r#" + pub const FOO: &'static str = env!("FOO"); + "#) + .file("tests/test.rs", r#" + extern crate foo; + + #[test] + fn test_foo() { + assert_eq!("foo", foo::FOO); + } + "#); + assert_that(p.cargo_process("test").arg("-v"), + execs().with_stderr(format!("\ +[COMPILING] foo v0.0.1 ({dir}) +[RUNNING] [..] build.rs [..] +[RUNNING] `[..][/]build-script-build` +[RUNNING] [..] --cfg foo[..] +[RUNNING] [..] --cfg foo[..] +[RUNNING] [..] --cfg foo[..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[RUNNING] `[..][/]foo-[..][EXE]` +[RUNNING] `[..][/]test-[..][EXE]` +[DOCTEST] foo +[RUNNING] [..] --cfg foo[..]", dir = p.url())) + .with_stdout(" +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured + + +running 1 test +test test_foo ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +")); +} + #[test] fn flags_go_into_tests() { let p = project("foo") @@ -1816,7 +1892,7 @@ fn fresh_builds_possible_with_link_libs() { rustc-flags = \"-l z -L ./\" ", target)) .file("build.rs", ""); - + assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0).with_stderr("\ [COMPILING] foo v0.5.0 ([..] @@ -1857,7 +1933,7 @@ fn fresh_builds_possible_with_multiple_metadata_overrides() { e = \"\" ", target)) .file("build.rs", ""); - + assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0).with_stderr("\ [COMPILING] foo v0.5.0 ([..] -- 2.30.2